package com.myapp.ruyixing.ui;

import static android.view.View.GONE;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.myapp.ruyixing.Config;
import com.myapp.ruyixing.R;
import com.myapp.ruyixing.http.RYHttpClient;
import com.myapp.ruyixing.http.RYHttpResponseHandler;
import com.myapp.ruyixing.model.CityList;
import com.myapp.ruyixing.model.CityList.City;
import com.myapp.ruyixing.ui.widget.TitleBar;
import com.myapp.ruyixing.utils.CompatibilityUtils;
import com.myapp.ruyixing.utils.KeyboardUtils;

public class CityListActivity extends Activity implements OnItemClickListener,
		OnClickListener, OnTouchListener {

	private static boolean sCityModified = false;

	private boolean mToSelectCity = false;
	private int mFrom = 0;
	private final static int LIVE_CITY = 1;
	private final static int TRAIN_CITY = 2;
	private final static int PLANE_CITY = 3;

	private CityListAdapter mAdapter;
	private ArrayList<City> mCityList;
	private ArrayList<City> mSearchCityList;
	private CitySearchListAdapter mSearchListAdapter;
	private HashMap<String, Integer> mIndexOfLetters = new HashMap<String, Integer>();
	private ListView mListView;
	private ListView mSearchListView;
	private ListView mIndexListView;
	private CityIndexAdapter mIndexAdapter;
	private String mUserCity;
	private String mUserCityId;
	private boolean mIsUserCityLegal = false;
	private TextView mGPSCity;
	private TextView mLetter;
	private EditText mSearchText;

	private RYHttpResponseHandler mHttpResponseHandler = new RYHttpResponseHandler() {

		@Override
		public void onSuccess(Object o) {
			try {
				CityList citylist = (CityList) o;
				onLoadingDataFinished(true, citylist);
			} catch (Exception e) {
				onLoadingDataFinished(false, null);
			}
		}

		@Override
		public void onFailure(Throwable throwable) {
			onLoadingDataFinished(false, null);
		}
	};

	private void showToast(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
	}

	private void showLoading(boolean show, String msg) {
		if (isFinishing()) {
			return;
		}
		if (show) {
			findViewById(R.id.layout_loading).setVisibility(View.VISIBLE);
			((TextView) findViewById(R.id.text_loading)).setText(msg);
		} else {
			findViewById(R.id.layout_loading).setVisibility(GONE);
		}
	}

	private void onLoadingDataStarted() {
		showLoading(true, "加载中");
		if (mToSelectCity) {
			if (mFrom == LIVE_CITY) {
				RYHttpClient.getLiveCityList(this, mHttpResponseHandler);
			} else if (mFrom == TRAIN_CITY) {
				RYHttpClient.getTrainCityList(this, mHttpResponseHandler);
			} else if (mFrom == PLANE_CITY) {
				RYHttpClient.getPlaneCityList(this, mHttpResponseHandler);
			}
		} else {
			RYHttpClient.getCityList(this, mHttpResponseHandler);
		}
	}

	private void initIndexOfLetters(ArrayList<City> list) {
		mIndexOfLetters.clear();
		for (int i = 0; i < list.size(); i++) {
			City city = list.get(i);
			if (city != null && !TextUtils.isEmpty(city.letters)) {
				char letter = city.letters.charAt(0);
				if (letter >= 'a' && letter <= 'z')
					letter = (char) (letter - ('a' - 'A'));
				if (letter >= 'A' && letter <= 'Z') {
					String l = letter + "";
					if (!mIndexOfLetters.containsKey(l)) {
						mIndexOfLetters.put(l, i);
					}
				}
			}
		}
	}

	private void initSearchList(String s) {
		s = s.toLowerCase();

		if (mSearchCityList == null) {
			mSearchCityList = new ArrayList<CityList.City>();
		}
		mSearchCityList.clear();

		if (mCityList != null) {
			for (City city : mCityList) {
				if (city.letters.contains(s) || city.cityname.contains(s)
						|| isFirstLetterMatch(city.letters, s)) {
					mSearchCityList.add(city);
				}
			}
		}
	}

	private boolean isFirstLetterMatch(String source, String pattern) {
		String firstLetters = "";
		for (String s : source.split(" ")) {
			if (s.length() > 0) {
				firstLetters += s.substring(0, 1);
			}
		}

		return firstLetters.contains(pattern);
	}

	private void onLoadingDataFinished(boolean succeed, CityList citylist) {
		showLoading(false, "");
		if (succeed && citylist != null) {
			if (citylist.list != null && citylist.list.size() > 0) {
				mCityList.clear();
				mCityList.addAll(citylist.list);
				initIndexOfLetters(mCityList);
				mAdapter.notifyDataSetChanged();
				for (City city : citylist.list) {
					if (!TextUtils.isEmpty(city.cityname)
							&& city.cityname.trim().startsWith(mUserCity)) {
						mGPSCity.setText(mUserCity);
						mUserCityId = city.cityid;
						mIsUserCityLegal = true;
						break;
					}
				}
			}
		} else {
			showToast("加载城市列表失败！");
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_city_list);
		if (getIntent().getBooleanExtra("modify_livecity", false)) {
			mToSelectCity = true;
			mFrom = LIVE_CITY;
		} else if (getIntent().getBooleanExtra("train_city", false)) {
			mToSelectCity = true;
			mFrom = TRAIN_CITY;
		} else if (getIntent().getBooleanExtra("plane_city", false)) {
			mToSelectCity = true;
			mFrom = PLANE_CITY;
		} else {
			mToSelectCity = false;
		}
		((TitleBar) findViewById(R.id.title_bar))
				.setOnIconClickedListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						onBackPressed();
					}
				});
		mGPSCity = (TextView) findViewById(R.id.city_gps);
		mGPSCity.setOnClickListener(this);
		mUserCity = Config.sMyLocation.getCity();
		if (!TextUtils.isEmpty(mUserCity)) {
			int index = mUserCity.lastIndexOf("市");
			if (index > 0)
				mUserCity = mUserCity.substring(0, index);
			mGPSCity.setText(mUserCity + (mToSelectCity ? "" : "(未开通)"));
		} else {
			mGPSCity.setText("无GPS定位城市");
		}
		mListView = (ListView) findViewById(R.id.list);
		mCityList = new ArrayList<City>();
		mAdapter = new CityListAdapter();
		mListView.setAdapter(mAdapter);
		mListView.setOnItemClickListener(this);
		mSearchListView = (ListView) findViewById(R.id.search_list);
		mSearchListAdapter = new CitySearchListAdapter();
		mSearchListView.setAdapter(mSearchListAdapter);
		mSearchListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long id) {
				if (id >= 0 && mSearchCityList != null
						&& id < mSearchCityList.size()) {
					if (mToSelectCity) {
						setResult(
								RESULT_OK,
								new Intent()
										.putExtra(
												"cityname",
												mSearchCityList.get((int) id).cityname)
										.putExtra(
												"cityid",
												mSearchCityList.get((int) id).cityid));
					} else {
						setCity(CityListActivity.this,
								mSearchCityList.get((int) id).cityname,
								mSearchCityList.get((int) id).cityid);
						KeyboardUtils.setKeyboardVisibility(
								CityListActivity.this, mSearchText, false);
					}
					finish();
				}
			}
		});
		mLetter = (TextView) findViewById(R.id.text_letter);

		mIndexAdapter = new CityIndexAdapter();
		mIndexListView = (ListView) findViewById(R.id.index_list);
		mIndexListView.setAdapter(mIndexAdapter);
		mIndexListView.setOnTouchListener(this);

		mSearchText = (EditText) findViewById(R.id.edit_search);
		mSearchText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				if (!TextUtils.isEmpty(s)) {
					initSearchList(s.toString());
					mSearchListView.setVisibility(View.VISIBLE);
					((BaseAdapter) mSearchListView.getAdapter())
							.notifyDataSetChanged();
				} else {
					mSearchListView.setVisibility(View.GONE);
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub

			}
		});

		onLoadingDataStarted();
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) {
		if (id >= 0 && mCityList != null && id < mCityList.size()) {
			if (mToSelectCity) {
				setResult(
						RESULT_OK,
						new Intent().putExtra("cityname",
								mCityList.get((int) id).cityname).putExtra(
								"cityid", mCityList.get((int) id).cityid));
			} else {
				setCity(this, mCityList.get((int) id).cityname,
						mCityList.get((int) id).cityid);
				KeyboardUtils.setKeyboardVisibility(this, mSearchText, false);
			}
			finish();
		}
	}

	private class CityIndexAdapter extends BaseAdapter {
		private List<String> mItems;

		public CityIndexAdapter() {
			mItems = new ArrayList<String>();
			for (int i = 'A'; i <= 'Z'; i++) {
				String l = (char) i + "";
				mItems.add(l);
			}
		}

		@Override
		public int getCount() {
			return mItems.size();
		}

		@Override
		public Object getItem(int position) {
			return mItems.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView indexName;

			if (convertView == null) {
				convertView = LayoutInflater.from(CityListActivity.this)
						.inflate(R.layout.city_list_index_item, parent, false);
			}

			indexName = (TextView) convertView.findViewById(R.id.index_name);
			String item = mItems.get(position);
			if (item != null) {
				indexName.setText(item);
			}

			return convertView;
		}

	}

	private class CityListAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return mCityList == null ? 0 : mCityList.size();
		}

		@Override
		public Object getItem(int position) {
			return mCityList == null ? null : mCityList.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			City city = (City) getItem(position);
			if (city == null) {
				return convertView;
			}
			if (convertView == null) {
				convertView = LayoutInflater.from(CityListActivity.this)
						.inflate(R.layout.text_city, parent, false);
			}
			if (!TextUtils.isEmpty(city.cityname)) {
				((TextView) convertView).setText(city.cityname);
			}
			return convertView;
		}
	}

	private class CitySearchListAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return mSearchCityList == null ? 0 : mSearchCityList.size();
		}

		@Override
		public Object getItem(int position) {
			return mSearchCityList == null ? null : mSearchCityList
					.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			City city = (City) getItem(position);
			if (city == null) {
				return convertView;
			}
			if (convertView == null) {
				convertView = LayoutInflater.from(CityListActivity.this)
						.inflate(R.layout.text_city, parent, false);
			}
			if (!TextUtils.isEmpty(city.cityname)) {
				((TextView) convertView).setText(city.cityname);
			}
			return convertView;
		}
	}

	public static boolean isCitySet(Context context) {
		SharedPreferences preferences = context.getSharedPreferences("city",
				CompatibilityUtils.hasHoneycomb() ? Context.MODE_MULTI_PROCESS
						: Context.MODE_PRIVATE);
		return preferences.getBoolean("set", false);
	}

	public static String getCityName(Context context) {
		SharedPreferences preferences = context.getSharedPreferences("city",
				CompatibilityUtils.hasHoneycomb() ? Context.MODE_MULTI_PROCESS
						: Context.MODE_PRIVATE);
		return preferences.getString("cityname", "");
	}

	public static String getCityId(Context context) {
		SharedPreferences preferences = context.getSharedPreferences("city",
				CompatibilityUtils.hasHoneycomb() ? Context.MODE_MULTI_PROCESS
						: Context.MODE_PRIVATE);
		return preferences.getString("cityid", "");
	}

	public static boolean checkCityModified() {
		boolean modified = sCityModified;
		sCityModified = false;
		return modified;
	}

	public static void setCity(Context context, String cityname, String cityid) {
		Config.sCityName = cityname;
		Config.sCityId = cityid;
		sCityModified = true;
		SharedPreferences preferences = context.getSharedPreferences("city",
				CompatibilityUtils.hasHoneycomb() ? Context.MODE_MULTI_PROCESS
						: Context.MODE_PRIVATE);
		Editor editor = preferences.edit();
		editor.putBoolean("set", true);
		editor.putBoolean("modified", true);
		editor.putString("cityname", cityname);
		editor.putString("cityid", cityid);
		editor.commit();
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.city_gps) {
			if (TextUtils.isEmpty(mUserCity)) {
				showToast("无定位城市，请开启定位！");
				return;
			}
			if (mIsUserCityLegal) {
				if (mToSelectCity) {
					setResult(RESULT_OK,
							new Intent().putExtra("cityname", mUserCity)
									.putExtra("cityid", mUserCityId));
				} else {
					setCity(this, mUserCity, mUserCityId);
				}
				finish();
			} else {
				showToast("此城市尚未开通，请选择其他城市！");
			}
		}
	}

	@Override
	public boolean onTouch(View view, MotionEvent event) {
		int position = -1;
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mIndexListView.setBackgroundColor(getResources().getColor(
					R.color.city_index_bg));
			// mIndexListView.setBackgroundResource(R.drawable.city_list_index_bg);
			position = mIndexListView.pointToPosition((int) event.getX(),
					(int) event.getY());
			break;
		case MotionEvent.ACTION_MOVE:
			position = mIndexListView.pointToPosition((int) event.getX(),
					(int) event.getY());
			break;
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			new Handler().postDelayed(new Runnable() {

				@Override
				public void run() {
					mLetter.setVisibility(View.GONE);
				}
			}, 200);
			mIndexListView.setBackgroundDrawable(null);
			break;
		default:
			break;
		}

		if (position >= 0 && position < mIndexAdapter.getCount()) {
			String item = (String) mIndexAdapter.getItem(position);
			if (!TextUtils.isEmpty(item)) {
				mLetter.setText(item);
				mLetter.setVisibility(View.VISIBLE);
				if (mIndexOfLetters.containsKey(item)) {
					int index = mIndexOfLetters.get(item);
					if (index >= 0 && index < mAdapter.getCount()) {
						mListView.setSelection(index);
					}
				}
			}
		}

		return false;
	}

}
